package org.vectrics.batch;

import java.util.Iterator;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.vectrics.SystemException;
import org.vectrics.domain.Domain;
import org.vectrics.hibernate.ApplicationContext;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.provider.CoreServiceLocator;

public abstract class VectricsQuartzJob implements Job {
	private transient Logger log = Logger.getLogger(VectricsQuartzJob.class); 
	public static ApplicationContext applicationContext = null;
	
	public VectricsQuartzJob() {
		super();
	}

	public String getName() {
		return(this.getClass().getName());
	}
	
	protected abstract void doExecute(Domain domain, ApplicationContext applicationContext) throws JobExecutionException;
	
	protected ApplicationContext getApplicationContext() {
		return(applicationContext);
	}
	
	
	public static void setApplicationContext(ApplicationContext applicationInformation) {
		VectricsQuartzJob.applicationContext = applicationInformation;
	}
	
	
	
	
	public final void execute(JobExecutionContext executionContext) throws JobExecutionException {
		String schedulerClass = executionContext.getScheduler().getClass().getName();
		/*
		if (1 == 1)
			throw new RuntimeException("Do not know how to handle execute request with JobExecutionContext passed" +
					"\r\n - Quartz Job Class: " + this.getClass().getName());
					*/
		
		this.execute(applicationContext);
	}
	
	public final void execute(ApplicationContext applicationContext) throws JobExecutionException {
		log.info("Running Quartz Job: " + this.getClass());
		try {
			if (applicationContext == null)
				throw new SystemException("ApplicationContext not set for JobExecutionContext - " +
						"discovered during Quartz triggering.  Job: " + this.getClass().getName());
			ThreadProperties.setApplicationContext(applicationContext);
			
			ThreadProperties.forcedCommitAndClose();
			Iterator doIter = CoreServiceLocator.getSystemService().findAllDomains().iterator();
			while (doIter.hasNext()) {
				Domain domain = (Domain)doIter.next();
				ThreadProperties.setDomain(domain);
				log.info("Running scheduled task" +
						"\r\n - Class      = " +  this.getClass().getName() +
						"\r\n - Task       = " +  this.getName() +
						"\r\n - Data Owner = " +  domain.getDescription()
						);
				try {
					this.doExecute(domain, applicationContext);
				} catch (Exception ex) {
					log.error("Exception executing batch job, class = " + this.getClass().getName(), ex);
					throw new SystemException("Exception executing batch job, class = " + this.getClass().getName(), ex);
				}
			}
		} catch (Exception ex) {
			log.error("Exception in batch job", ex);
			throw new RuntimeException("Exception running batch job", ex);
		} finally {
			ThreadProperties.closeSession();
		}
		
	}

}
